home *** CD-ROM | disk | FTP | other *** search
/ MacTech 1 to 12 / MacTech-vol-1-12.toast / Source / MacTech® Magazine / Volume 11 - 1995 / 11.02 Feb 95 / Yenta / Erics C++ Libraries / PPC Classes / CPPWriteTask.cp < prev    next >
Encoding:
Text File  |  1996-04-04  |  6.5 KB  |  216 lines  |  [TEXT/KAHL]

  1. /********************************************************* DEFINITION
  2.     DATE:    9/17/93
  3.     AUTHOR: Eric R. Rosé
  4.  
  5.     CLASS:  CPPWriteTask
  6.     
  7.     SUPERCLASS: CPPPeriodicTask
  8.     
  9.         This C++ class lets you write data asynchronously through a  
  10.         PPC connection.
  11.     
  12. ********************************************************************/
  13.  
  14. #include <CPPWriteTask.h>
  15. #include <CPPTaskManager.h>
  16. #include <MemoryTools.h>
  17. #include <CPPNodeInfo.h>
  18. #include <ToolboxTools.h>
  19. #include <StringTools.h>
  20. #include <script.h>
  21.  
  22. /*-----------------------------------------------------------------*/
  23. /*----------------------- INTERNAL CONSTANTS ----------------------*/
  24. /*-----------------------------------------------------------------*/
  25.  
  26. #define        kSync            FALSE    
  27. #define        kAsync            TRUE
  28.  
  29. /*-----------------------------------------------------------------*/
  30. /*------------------------ PUBLIC METHODS -------------------------*/
  31. /*-----------------------------------------------------------------*/
  32.  
  33.     CPPWriteTask::CPPWriteTask (CPPTaskManager *TaskManager, 
  34.                                 long minPeriod, 
  35.                                 Boolean deleteWhenDone) :
  36.                                   CPPPeriodicTask (TaskManager, minPeriod,
  37.                                                  deleteWhenDone)
  38.     {
  39.         this->data = NULL;
  40.         this->ownsData = FALSE;
  41.         this->dataLen = 0;
  42.         this->sessionID = 0;
  43.         this->writePBPtr = NULL;
  44.     }
  45.     
  46. /*-----------------------------------------------------------------*/
  47.  
  48.     CPPWriteTask::~CPPWriteTask (void)
  49.     {
  50.         PPCClosePBRec    CloseRec;
  51.     
  52.         // if there is a write call outstanding, close the session
  53.         if (this->writePBPtr)
  54.           if (this->writePBPtr->ioResult == 1)
  55.             {
  56.               CloseRec.portRefNum = this->sessionID;
  57.               PPCClose(&CloseRec, FALSE);
  58.             }
  59.     
  60.         // dispose of the data and control pointers
  61.         NukePtr(this->writePBPtr);
  62.         if (this->ownsData)
  63.           NukePtr(this->data);
  64.     }
  65.     
  66. /*-----------------------------------------------------------------*/
  67.  
  68.     char *CPPWriteTask::ClassName (void)
  69.     {
  70.         return "CPPWriteTask";
  71.     }
  72.  
  73. /*-----------------------------------------------------------------*/
  74.  
  75.     void CPPWriteTask::StartWriteTask (PPCPortRefNum SourcePortRefNum,
  76.                                        CPPNodeInfo *SendTo,
  77.                                        Ptr DataToWrite, Boolean OwnsData,
  78.                                        CompletionProc DoProc,
  79.                                        OSType DataType, OSType DataCreator)
  80.     /* Open a connection between SourcePort and SendTo, then */
  81.     /* set up the write parameter block and make the write call */
  82.     {
  83.         EntityName        TheName;
  84.         StringPtr        ObjStr = NULL, TypeStr = NULL, ZoneStr = NULL;
  85.         LocationNameRec    *LocationRec = (LocationNameRec    *)NewPtrClear(sizeof(LocationNameRec));
  86.         PPCStartPBRec    StartRec;
  87.         OSErr            ErrCode;
  88.         PortInfoRec        *PortRec = (PortInfoRec *)NewPtrClear(sizeof(PortInfoRec));
  89.         StringPtr        PName = PortRec->name.name;
  90.         short            i = 1;
  91.         
  92.         if (!this->hasCompleted)
  93.           return;
  94.         
  95.         // fill in the Location Rec with data from the SendTo object;
  96.         SendTo->GetNodeName (&ObjStr, &TypeStr, &ZoneStr);
  97.         CopyString (ObjStr, TheName.objStr);
  98.         CopyString (TypeStr, TheName.typeStr);
  99.         CopyString (ZoneStr, TheName.zoneStr);
  100.         LocationRec->locationKindSelector = ppcNBPLocation;
  101.         LocationRec->u.nbpEntity = TheName;
  102.  
  103.         // fill in the PPCPortRec with the destination port name
  104.         PortRec->name.nameScript = smRoman;
  105.  
  106.         CopyString(TypeStr, PName);
  107.         while (((PName[i] & 0x00FF) != 0xA5) && (i <= PName[0]))
  108.           i++;
  109.         PName[0] = i-1;
  110.         PortRec->name.portKindSelector = ppcByString;
  111.         CopyString ("\pPPCCommPort", PortRec->name.u.portTypeStr);
  112.  
  113.         // fill in the 'start session' record
  114.         StartRec.ioCompletion = NULL;
  115.         StartRec.portRefNum = SourcePortRefNum;
  116.         StartRec.serviceType = ppcServiceRealTime;
  117.         StartRec.resFlag = 0;
  118.         StartRec.portName = &PortRec->name;
  119.         StartRec.locationName = LocationRec;
  120.         StartRec.userData = 0;
  121.         StartRec.userRefNum = 0;        // guest access
  122.         
  123.         // Try to open the connection; if we can, create a WriteTask
  124.         // to send the data to the other machine asynchronously
  125.         if ((ErrCode = PPCStart (&StartRec, FALSE)) != noErr)    
  126.           ErrorAlert (ErrCode, "\pCould not send the message");
  127.         else
  128.           // call the other StartWriteTask method to finish the job
  129.           this->StartWriteTask(DataToWrite, ownsData, 
  130.                                  StartRec.sessRefNum, DoProc,
  131.                                  DataType, DataCreator);
  132.         
  133.         // dispose of the memory used by the PPCStart routine
  134.         NukePtr(PortRec);
  135.         NukePtr(LocationRec);
  136.     }
  137.  
  138.  
  139. /*-----------------------------------------------------------------*/
  140.  
  141.     void CPPWriteTask::StartWriteTask (Ptr DataToWrite, Boolean OwnsData,
  142.                                         PPCSessRefNum ConnectionID,
  143.                                         CompletionProc DoProc,
  144.                                         OSType DataType, OSType DataCreator)
  145.     /* Set up the write parameter block and make the call, assuming */
  146.     /* that a connection is already open and its refnum is passed in */
  147.     /* ConnectionID */
  148.     {
  149.         this->SetCompletionProc(DoProc);
  150.         
  151.         if (!this->hasCompleted)
  152.           return;
  153.         
  154.         this->writePBPtr = (PPCWritePBPtr)NewPtrClear(sizeof(PPCWritePBRec));
  155.         if ((this->callResult = MemError()) == noErr)
  156.           {
  157.             // initialize the data tracking variables
  158.             this->data = DataToWrite;
  159.             this->ownsData = OwnsData;
  160.             this->dataLen = GetPtrSize(DataToWrite);
  161.             this->sessionID = ConnectionID;
  162.             
  163.             // set up the WritePB's fields
  164.             this->writePBPtr->ioCompletion = NULL;
  165.             this->writePBPtr->sessRefNum = ConnectionID;
  166.             this->writePBPtr->bufferLength = this->dataLen;
  167.             this->writePBPtr->bufferPtr = DataToWrite;
  168.             this->writePBPtr->more = FALSE;
  169.             this->writePBPtr->userData = this->dataLen;
  170.             this->writePBPtr->blockCreator = DataCreator;
  171.             this->writePBPtr->blockType = DataType;
  172.             
  173.             // make the call to write the data asynchronously
  174.             if ((this->callResult = PPCWrite(this->writePBPtr, kAsync)) == noErr)
  175.               {
  176.                 this->hasCompleted = FALSE;            // note that we are not done
  177.                 this->ourManager->AddPeriodicTask(this);    // now add the task
  178.                   return;
  179.               }
  180.           }
  181.           
  182.         // we will reach this line if memory allocation or PPCWrite fails
  183.         NukePtr (this->writePBPtr);
  184.     }
  185.     
  186. /*-----------------------------------------------------------------*/
  187.  
  188.     void CPPWriteTask::DoPeriodicAction (void)
  189.     /* if the write has completed or failed, store the result code */
  190.     /* and note that we are done */
  191.     {
  192.         // call the inherited method to update frequency count
  193.         CPPPeriodicTask::DoPeriodicAction();
  194.  
  195.         if (this->writePBPtr->ioResult != 1)
  196.           {
  197.               this->callResult = this->writePBPtr->ioResult;
  198.               this->hasCompleted = TRUE;
  199.               
  200.               if (this->callResult != noErr)
  201.                 SysBeep(1);
  202.           }
  203.     }
  204.  
  205. /*-----------------------------------------------------------------*/
  206.  
  207.     void CPPWriteTask::DoCompletedAction(void)
  208.     {
  209.         // release the memory we allocated
  210.         NukePtr(this->writePBPtr);
  211.         if (this->ownsData)
  212.           NukePtr(this->data);
  213.           
  214.         CPPPeriodicTask::DoCompletedAction();
  215.     }
  216.